#include"StdAfx.h"

#ifdef IOS_REF
	#undef  IOS_REF
	#define IOS_REF (*(pFbxManager->GetIOSettings()))
#endif


pgRenderableObject* pgFBXLoader::LoadMesh(const char* szFilePath)
{
	PG_LOG_INFO_EX(TOPIC_FBXLOADER, "Loader is loading object: %s!", szFilePath);

	FbxManager *pFbxManager = NULL;
	FbxScene *pFbxScene = NULL;

	// Initialize the FBX objects..
	pFbxManager = FbxManager::Create();

	if (!pFbxManager)
	{
		PG_LOG_WARNING_EX(TOPIC_FBXLOADER, "Failed to create FbxManager! Aborting...");
		return false;
	}

	PG_LOG_INFO_EX(TOPIC_FBXLOADER, "FBX Version: %s", pFbxManager->GetVersion());

	FbxIOSettings *pIOS = FbxIOSettings::Create(pFbxManager, IOSROOT);
	pFbxManager->SetIOSettings(pIOS);

	pFbxScene = FbxScene::Create(pFbxManager, szFilePath);

	if (!pFbxScene)
	{
		PG_LOG_WARNING_EX(TOPIC_FBXLOADER, "Failed to create scene for %s. Aboting...", szFilePath);
		return false;
	}

	// Start loading scene

	  int lFileMajor, lFileMinor, lFileRevision;
    int lSDKMajor,  lSDKMinor,  lSDKRevision;
    int i, lAnimStackCount;
    bool lStatus;
    char lPassword[1024];

    // Get the file version number generate by the FBX SDK.
    FbxManager::GetFileFormatVersion(lSDKMajor, lSDKMinor, lSDKRevision);

    // Create an importer.
    FbxImporter* lImporter = FbxImporter::Create(pFbxManager, "");

    // Initialize the importer by providing a filename.
	bool lImportStatus = lImporter->Initialize(szFilePath, -1, pFbxManager->GetIOSettings());

	lImporter->GetFileVersion(lFileMajor, lFileMinor, lFileRevision);


    if( !lImportStatus )
    {
        PG_LOG_WARNING_EX(TOPIC_FBXLOADER,"Call to FbxImporter::Initialize() failed.");
        PG_LOG_WARNING_EX(TOPIC_FBXLOADER,"Error returned: %s", lImporter->GetLastErrorString());

        if (lImporter->GetLastErrorID() == FbxIOBase::eFileVersionNotSupportedYet ||
            lImporter->GetLastErrorID() == FbxIOBase::eFileVersionNotSupportedAnymore)
        {
            PG_LOG_WARNING_EX(TOPIC_FBXLOADER,"FBX file format version for this FBX SDK is %d.%d.%d", lSDKMajor, lSDKMinor, lSDKRevision);
            PG_LOG_WARNING_EX(TOPIC_FBXLOADER,"FBX file format version for file '%s' is %d.%d.%d", szFilePath, lFileMajor, lFileMinor, lFileRevision);
        }

        return false;
    }

    PG_LOG_INFO_EX(TOPIC_FBXLOADER,"FBX file format version for this FBX SDK is %d.%d.%d", lSDKMajor, lSDKMinor, lSDKRevision);

    if (lImporter->IsFBX())
    {
        PG_LOG_INFO_EX(TOPIC_FBXLOADER,"FBX file format version for file '%s' is %d.%d.%d", szFilePath, lFileMajor, lFileMinor, lFileRevision);

        // From this point, it is possible to access animation stack information without
        // the expense of loading the entire file.

        PG_LOG_INFO_EX(TOPIC_FBXLOADER,"Animation Stack Information");

        lAnimStackCount = lImporter->GetAnimStackCount();

        PG_LOG_INFO_EX(TOPIC_FBXLOADER,"    Number of Animation Stacks: %d", lAnimStackCount);
        PG_LOG_INFO_EX(TOPIC_FBXLOADER,"    Current Animation Stack: \"%s\"", lImporter->GetActiveAnimStackName().Buffer());
        PG_LOG_INFO_EX(TOPIC_FBXLOADER,"\n");

        for(i = 0; i < lAnimStackCount; i++)
        {
            FbxTakeInfo* lTakeInfo = lImporter->GetTakeInfo(i);

            PG_LOG_INFO_EX(TOPIC_FBXLOADER,"    Animation Stack %d", i);
            PG_LOG_INFO_EX(TOPIC_FBXLOADER,"         Name: \"%s\"", lTakeInfo->mName.Buffer());
            PG_LOG_INFO_EX(TOPIC_FBXLOADER,"         Description: \"%s\"", lTakeInfo->mDescription.Buffer());

            // Change the value of the import name if the animation stack should be imported 
            // under a different name.
            PG_LOG_INFO_EX(TOPIC_FBXLOADER,"         Import Name: \"%s\"", lTakeInfo->mImportName.Buffer());

            // Set the value of the import state to false if the animation stack should be not
            // be imported. 
            PG_LOG_INFO_EX(TOPIC_FBXLOADER,"         Import State: %s", lTakeInfo->mSelect ? "true" : "false");
        }

        // Set the import states. By default, the import states are always set to 
        // true. The code below shows how to change these states.
		pFbxManager->GetIOSettings()->SetBoolProp(IMP_FBX_MATERIAL,        true);
        pFbxManager->GetIOSettings()->SetBoolProp(IMP_FBX_TEXTURE,         true);
        pFbxManager->GetIOSettings()->SetBoolProp(IMP_FBX_LINK,            true);
        pFbxManager->GetIOSettings()->SetBoolProp(IMP_FBX_SHAPE,           true);
        pFbxManager->GetIOSettings()->SetBoolProp(IMP_FBX_GOBO,            true);
        pFbxManager->GetIOSettings()->SetBoolProp(IMP_FBX_ANIMATION,       true);
        pFbxManager->GetIOSettings()->SetBoolProp(IMP_FBX_GLOBAL_SETTINGS, true);
    }

    // Import the scene.
    lStatus = lImporter->Import(pFbxScene);

  
    // Destroy the importer.
    lImporter->Destroy();

	FbxNode *pNode = pFbxScene->GetRootNode();
	pgMesh *pPGMesh = new NEW_MEM_LEAK pgMesh();

	for (int i = 0; i < pNode->GetChildCount(); ++i)
	{
		if (pNode->GetChild(i)->GetNodeAttribute()->GetAttributeType() == FbxNodeAttribute::eMesh)
		{
			FbxMesh *pMesh = (FbxMesh*)(pNode->GetChild(i)->GetNodeAttribute());
			int vertexCount = pMesh->GetControlPointsCount();
			FbxVector4	*pFbxVerts = pMesh->GetControlPoints();

			SVertex *pVerts = new NEW_MEM_LEAK SVertex[vertexCount];

			for (int i = 0; i < vertexCount; ++i)
			{
				pVerts[i].pos.x	= pFbxVerts[i].mData[0];
				pVerts[i].pos.y	= pFbxVerts[i].mData[1];
				pVerts[i].pos.z	= pFbxVerts[i].mData[2];
			}

			pPGMesh->SetVertices(pVerts, vertexCount);


			int polyCount = pMesh->GetPolygonCount();
			PG_LOG_INFO_EX(TOPIC_FBXLOADER, "Vertex count; %d , polygon count: %d !", vertexCount, polyCount);

			int *indices = pMesh->GetPolygonVertices();
			
			int overAllCount = 0;

			for (int j = 0; j < polyCount; ++j)
			{
				overAllCount += pMesh->GetPolygonSize(j);
			}

			
			PG_LOG_INFO_EX(TOPIC_FBXLOADER, "Index count: %d !", overAllCount);

			WORD *realIndices = new NEW_MEM_LEAK WORD[overAllCount];

			for (int j = 0; j < overAllCount; ++j)
			{
				realIndices[j] = indices[j];
			}

			pPGMesh->SetIndices(realIndices, overAllCount);
			
			break;
		}
	}

	pFbxManager->Destroy();

	pgRenderableObject *pObj = new pgRenderableObject();
	
	pObj->SetMesh(pPGMesh);


	PG_LOG_INFO_EX(TOPIC_FBXLOADER, "Finished loading file: %s!", szFilePath); 
	return pObj;
}